////
/// @group tabs
////

@use "sass:map";

@use "../utils";
@use "../spacing";
@use "../theme/theme";
@use "../transition/transition";
@use "../typography/typography";
@use "../interaction/interaction";
@use "../icon/icon";
@use "../button/button";

/// Set to `true` to disable all the styles
/// @type Boolean
$disable-everything: false !default;

/// Set to `true` to disable the icon support within a `Tab`.
/// @type Boolean
$disable-icon: false !default;

/// Set to `true` to disable the stacked `Tab` styles.
/// @type Boolean
$disable-stacked: false !default;

/// Set to `true` to disable the reversed `Tab` styles.
/// @type Boolean
$disable-reversed: false !default;

/// Set to `true` to disable the padded `TabList` styles.
/// @type Boolean
$disable-tablist-padded: false !default;

/// Set to `true` to disable the vertical `TabList` styles.
/// @type Boolean
$disable-tablist-vertical: false !default;

/// Set to `true` if the active tab indicator animation is not required due to
/// all `TabList` components enabling the `disableTransition` prop and all
/// `Tab` components enable the `tabIndicator` prop.
/// @type Boolean
$disable-tablist-indicator: false !default;

/// Set to `true` to disable the hidden scrollbar styles on the `TabList`.
/// @type Boolean
$disable-tablist-hidden-scrollbar: false !default;

/// Set to `true` to disable the styles for the scroll buttons within the
/// `TabList`.
/// @type Boolean
$disable-tablist-scroll-button: false !default;

/// Set to `true` to disable the active tab indicator animation from the
/// `TabList` component.
///
/// @type Boolean
$disable-tablist-active-indicator-transition: $disable-tablist-indicator !default;

/// Set to `true` to disable the icon support within a `Tab`.
/// @type Boolean
$disable-tablist-scroll-button-vertical: $disable-tablist-vertical !default;

/// Set to `true` to disable the active tab indicator styles.
/// @type Boolean
$disable-indicator: false !default;

/// Set to `true` to disable the vertical active tab indicator styles.
/// @type Boolean
$disable-indicator-vertical: $disable-tablist-vertical !default;

/// The default `Tab` typography.
/// @type Map
$typography: map.remove(typography.$button-styles, line-height) !default;

/// The default gap between the `Tab` icon and children.
/// @type Number
$gap: spacing.get-var(sm) !default;

/// The default `Tab` height.
/// @type Number
$height: 3rem !default;

/// The default `Tab` stacked height.
/// @type Number
$stacked-height: 4.5rem !default;

/// The default `Tab` horizontal padding.
/// @type Number
$horizontal-padding: spacing.get-var(md) !default;

/// The default `Tab` vertical padding while `stacked`.
/// @type Number
$vertical-padding: calc(spacing.get-var(sm) * 1.5) !default;

/// The `Tab` min width.
/// @type Number
$min-width: 5.625rem !default;

/// The `Tab` max width.
/// @type Number
$max-width: 20rem !default;

/// The default height for the active tab indicator.
/// @type Number
$indicator-height: 0.125rem !default;

/// The default background-color for the active tab indicator.
/// @type Color
$indicator-background: theme.theme-get-var(primary-color) !default;

/// The default text color for an active `Tab`.
/// @type Color
$active-color: theme.theme-get-var(text-primary-color) !default;

/// The default text color for an inactive `Tab`.
/// @type Color
$inactive-color: theme.theme-get-var(text-secondary-color) !default;

/// The default text color for a disabled `Tab`.
/// @type Color
$disabled-color: theme.theme-get-var(text-disabled-color) !default;

/// The default transition duration for the active tab indicator.
/// @type Number
$transition-duration: transition.$linear-duration !default;

/// The default transition timing function for the active tab indicator.
/// @type Number
$transition-timing-function: transition.$linear-timing-function !default;

/// The default padding for a `TabList` with the `padded` prop enabled.
/// @type Number
$tablist-scrollable-horizontal-padding: calc(
  spacing.get-var(xl) * 1.625
) !default;

/// The default z-index for a `TabList` scroll button.
/// @type Number
$tablist-scroll-button-z-index: 2 !default;

/// The default background color for a `TabList` scroll button.
/// @type Number
$tablist-scroll-button-background-color: theme.theme-get-var(
  background-color,
  inherit
) !default;

/// The default `top` or `left` position for the active tab indicator relative
/// to the `TabList` container.
///
/// @type Number
$tablist-vertical-indicator-position: 0 !default;

/// The `border-radius` for the `TabListScrollButton`.
/// @type Number
$tablist-button-border-radius: 0 !default;

/// The available configurable css variables and mostly used internally for the
/// `get-var`, `set-var`, and `use-var` utils.
/// @type List
$variables: (
  color,
  active-color,
  inactive-color,
  disabled-color,
  indicator-background,
  min-height,
  max-width,
  min-width,
  stacked-height,
  stacked-width,
  padding,
  stacked-padding
);

/// @param {String} name - The supported variable name
/// @param {any} fallback [null] - An optional fallback value
/// @returns {String} a `var()` statement
@function get-var($name, $fallback: null) {
  $var: utils.get-var-name($variables, $name, "tab");
  @if $fallback {
    @return var(#{$var}, #{$fallback});
  }

  @return var(#{$var});
}

/// @param {String} name - The supported variable name
/// @param {any} value - The value to set the variable to. Supports `null` which
/// will just be a no-op.
@mixin set-var($name, $value) {
  @if $value {
    #{utils.get-var-name($variables, $name, "tab")}: #{$value};
  }
}

/// @param {String} property - The css property to apply the variable to
/// @param {String} name [$property] - The supported variable name
/// @param {any} fallback [null] - An optional fallback value if the variable
/// has not been set
@mixin use-var($property, $name: $property, $fallback: null) {
  #{$property}: get-var($name, $fallback);
}

/// This should only be used if not using the `tab-styles` mixin.
///
/// @see {mixin} styles
@mixin indicator-styles {
  .rmd-tab-indicator {
    &::after {
      @include use-var(
        background,
        indicator-background,
        theme.theme-color-var-fallback($indicator-background)
      );

      content: "";
      pointer-events: none;
      position: absolute;
      z-index: 1;
    }

    &--h::after {
      bottom: 0;
      height: $indicator-height;
      width: 100%;
    }

    @if not $disable-indicator-vertical {
      &--v::after {
        height: 100%;
        right: $tablist-vertical-indicator-position;
        top: 0;
        width: $indicator-height;

        @include utils.rtl {
          left: $tablist-vertical-indicator-position;
          right: auto;
        }
      }
    }

    @if not $disable-tablist-indicator {
      &--tablist-h::after {
        left: 0;
        max-width: var(--rmd-tab-size, $min-width);
        transform: translateX(var(--rmd-tab-offset, 0));
      }

      @if not $disable-tablist-vertical {
        &--tablist-v::after {
          max-height: var(--rmd-tab-size, $min-width);
          transform: translateY(var(--rmd-tab-offset, 0));
        }
      }
    }

    @if not $disable-tablist-active-indicator-transition {
      &--animate::after {
        transition-duration: $transition-duration;
        transition-property: transform, max-width;
        transition-timing-function: $transition-timing-function;
      }
    }
  }
}

/// This should only be used if not using the `tab-styles` mixin.
///
/// @see {mixin} styles
@mixin tablist-styles {
  .rmd-tablist {
    display: inline-flex;
    // disable shrinking since tabs should normally be full width and this
    // also fixes issues when placed within a flex column container
    flex-shrink: 0;
    flex-wrap: nowrap;
    // make sure it can enable scrollbars in flex/grid containers
    max-width: 100%;
    outline: none;
    overflow: auto;
    position: relative;

    &--full-width {
      display: flex;
      width: 100%;
    }

    &--full-width-tabs {
      @include set-var(min-width, none);
    }

    @if not $disable-tablist-hidden-scrollbar {
      &--no-scrollbar {
        @include utils.hide-scrollbar;
      }
    }

    @if not $disable-tablist-vertical {
      &--vertical {
        flex-direction: column;
      }
    }

    @if not $disable-tablist-padded {
      &--padded {
        padding-left: $tablist-scrollable-horizontal-padding;

        @include utils.rtl {
          padding-left: 0;
          padding-right: $tablist-scrollable-horizontal-padding;
        }
      }
    }

    &--center {
      justify-content: center;
    }
  }
}

/// This should only be used if not using the `tab-styles` mixin.
///
/// @see {mixin} styles
@mixin tablist-button-styles {
  .rmd-tablist-button {
    @include button.set-var(icon-border-radius, $tablist-button-border-radius);

    align-items: center;
    background-color: $tablist-scroll-button-background-color;
    display: inline-flex;
    flex-shrink: 0;
    justify-content: center;
    max-width: $max-width;
    position: sticky;
    z-index: $tablist-scroll-button-z-index;

    &--left {
      left: 0;
    }

    &--right {
      right: 0;
    }

    @if not $disable-tablist-scroll-button-vertical {
      &--above {
        top: 0;
      }

      &--below {
        bottom: 0;
      }
    }

    &__button {
      @if not $disable-tablist-scroll-button-vertical {
        &--v {
          width: 100%;

          :where(.rmd-icon) {
            transform: rotate(90deg);
          }
        }
      }
    }

    @include utils.rtl {
      $button-selector: "&__button" +
        if(
          $disable-tablist-scroll-button-vertical,
          "",
          ":where(:not(.rmd-tablist-button__button--v))"
        );

      &--left {
        left: auto;
        right: 0;
      }

      &--right {
        left: 0;
        right: auto;
      }

      #{$button-selector} {
        transform: rotate(180deg);
      }
    }
  }
}

/// This should only be used if not using the `tab-styles` mixin.
///
/// @see {mixin} styles
@mixin tab-styles {
  .rmd-tab {
    @include utils.map-to-styles($typography);
    @include use-var(
      color,
      $fallback: theme.theme-color-var-fallback($inactive-color)
    );
    @include use-var(min-height);
    @include use-var(max-width);
    @include use-var(min-width);
    @include use-var(padding);
    @if not $disable-icon {
      @include icon.set-var(color, currentcolor);
    }

    align-items: center;
    background-color: transparent;
    border-width: 0;
    display: inline-flex;
    flex: 1 0 auto;
    gap: $gap;
    justify-content: center;
    transition: color $transition-duration $transition-timing-function;

    @if not $disable-stacked {
      &--stacked {
        @include use-var(height, stacked-height);
        @include use-var(padding, stacked-padding);

        flex-direction: column;
      }

      @if not $disable-reversed {
        &--stacked-reversed {
          flex-direction: column-reverse;
        }
      }
    }

    @if not $disable-reversed {
      &--reversed {
        flex-direction: row-reverse;
      }
    }

    &--active {
      @include set-var(
        color,
        get-var(active-color, theme.theme-color-var-fallback($active-color))
      );
    }

    &--disabled {
      @include set-var(
        color,
        get-var(disabled-color, theme.theme-color-var-fallback($disabled-color))
      );
    }
  }
}

/// Conditionally applies the css variables based on feature flags
@mixin variables {
  @if not $disable-everything {
    @if not theme.is-theme-color-var($inactive-color) {
      @include set-var(color, $inactive-color);
    }

    @if not theme.is-theme-color-var($active-color) {
      @include set-var(active-color, $active-color);
    }

    @if not theme.is-theme-color-var($disabled-color) {
      @include set-var(disabled-color, $disabled-color);
    }
    @include set-var(min-height, $height);
    @include set-var(max-width, $max-width);
    @include set-var(min-width, $min-width);
    @include set-var(padding, 0 $horizontal-padding);

    @if not $disable-stacked {
      @include set-var(stacked-height, $stacked-height);
      @include set-var(stacked-padding, $vertical-padding $horizontal-padding);
    }

    @if not
      $disable-indicator and not
      theme.is-theme-color-var($indicator-background)
    {
      @include set-var(indicator-background, $indicator-background);
    }
  }
}

/// Generates all the styles based on feature flags.
///
/// @param {Boolean} disable-layer [false] - Set this to `true` to disable the
/// layer behavior
@mixin styles($disable-layer: false) {
  @if not $disable-everything {
    @include utils.optional-layer(tabs, $disable-layer) {
      @include tablist-styles;
      @include tab-styles;

      @if not $disable-indicator {
        @include indicator-styles;
      }

      @if not $disable-tablist-scroll-button {
        @include tablist-button-styles;
      }
    }
  }
}
